﻿using RuoVea.ExCrypt.Encryptions.Domain;
using RuoVea.ExCrypt.Extensions;
using System;
using System.Security.Cryptography;
using System.Text;

namespace RuoVea.ExCrypt
{
    /// <summary>
    /// 创建人：starry
    /// 日 期：2017.03.06
    /// 描 述：MD5加密类
    /// </summary>
    public class Md5Crypt
    {
        #region JSMd5加密的字符串
        /// <summary>
        /// JSMd5加密的字符串
        /// </summary>
        /// <param name="str">加密的字符串</param>
        /// <returns>JSMd5加密的字符串</returns>
        public static string JsMD5(string str)
        {
            using (MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider())
            {
                byte[] bytes = Encoding.UTF8.GetBytes(str);
                byte[] array = mD5CryptoServiceProvider.ComputeHash(bytes);
                StringBuilder sb = new StringBuilder();
                foreach (var a in array)
                {
                    sb.AppendFormat("{0:x2}", a);
                }
                return sb.ToString();
            }
        }
        #endregion

        #region HMACMD5
        /// <summary>
        /// HMACMD5 hash
        /// </summary>
        /// <param name="srcString">The string to be encrypted</param>
        /// <param name="key">encrypte key</param>
        /// <returns></returns>
        public static string HMACMD5(string srcString, string key)
        {
            Check.Argument.IsNotEmpty(srcString, nameof(srcString));
            Check.Argument.IsNotEmpty(key, nameof(key));

            byte[] secrectKey = Encoding.UTF8.GetBytes(key);
            using (HMACMD5 md5 = new HMACMD5(secrectKey))
            {
                byte[] bytes_md5_in = Encoding.UTF8.GetBytes(srcString);
                byte[] bytes_md5_out = md5.ComputeHash(bytes_md5_in);
                string str_md5_out = BitConverter.ToString(bytes_md5_out);
                str_md5_out = str_md5_out.Replace("-", "");
                return str_md5_out;
            }
        }
        #endregion

        #region MD5加密

        /// <summary>
        /// 32位MD5加密（小写）
        /// </summary>
        /// <param name="input">输入字段</param>
        /// <returns>MD5加密字符串</returns>
        public static string Hash(string input)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }
        #endregion

        #region MD5加密字符串处理
        /// <summary>
        /// MD5加密字符串处理 MD5 hash 
        /// </summary>
        /// <param name="srcString">The string to be encrypted.</param>
        /// <param name="length">The length of hash result , default value is <see cref="EnumMD5Length.L32"/>.</param>
        /// <returns></returns>
        public static string Encrypt(string srcString, EnumMD5Length length = EnumMD5Length.L32)
        {
            Check.Argument.IsNotEmpty(srcString, nameof(srcString));

            string str_md5_out = string.Empty;
            using (MD5 md5 = MD5.Create())
            {
                byte[] bytes_md5_in = Encoding.UTF8.GetBytes(srcString);
                byte[] bytes_md5_out = md5.ComputeHash(bytes_md5_in);

                str_md5_out = length == EnumMD5Length.L32
                    ? BitConverter.ToString(bytes_md5_out)
                    : BitConverter.ToString(bytes_md5_out, 4, 8);

                str_md5_out = str_md5_out.Replace("-", "");
                return str_md5_out;
            }
        }
        #endregion
    }
}

